#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
A股中长期投资分析系统
专注于筛选和分析具有投资价值的股票

投资策略：
- 市值50亿以上的稳健企业
- 股价4-20元区间的合理价位
- 市盈率合理的盈利公司
- 优先考虑有分红的公司
- 预测未来1个月趋势
"""

import sys
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')

# 添加项目路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from real_data_fetcher import RealDataFetcher
from simple_technical_analysis import SimpleTechnicalAnalysis
from simple_prediction_model import SimplePredictionModel
from simple_stock_screener import SimpleStockScreener
# 删除不必要的导入

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

class MediumTermInvestmentAnalyzer:
    """中长期投资分析器"""
    
    def __init__(self):
        self.data_fetcher = RealDataFetcher()
        self.technical_analyzer = SimpleTechnicalAnalysis()
        self.prediction_model = SimplePredictionModel()
        self.stock_screener = SimpleStockScreener()
        
        # 投资策略配置
        self.criteria = {
            'min_market_cap': 50,      # 50亿市值
            'max_market_cap': 2000,    # 2000亿市值上限
            'min_price': 4,            # 4元最低价
            'max_price': 20,           # 20元最高价
            'max_pe_ratio': 30,        # 市盈率上限
            'min_pe_ratio': 5,         # 市盈率下限
            'dividend_preferred': True, # 优先分红股
            'min_roe': 0.05,           # 最低ROE 5%
        }
        
        self.selected_stocks = []
        self.analysis_results = {}
        
    def print_header(self, title):
        print(f"\n{'='*80}")
        print(f"🎯 {title}")
        print(f"{'='*80}")
        
    def print_success(self, message):
        print(f"✅ {message}")
        
    def print_info(self, message):
        print(f"📊 {message}")
        
    def print_warning(self, message):
        print(f"⚠️  {message}")
        
    def screen_potential_stocks(self):
        """筛选具有投资潜力的股票"""
        self.print_header("第一步：筛选符合投资条件的股票")
        
        try:
            # 获取A股列表
            print("📈 获取A股股票列表...")
            stock_list = self.data_fetcher.get_stock_list()
            
            if stock_list.empty:
                print("❌ 无法获取股票列表")
                return []
            
            self.print_success(f"获取到 {len(stock_list)} 只A股")
            
            # 对股票进行筛选（为了快速演示，先筛选部分股票）
            print("🔍 开始筛选符合条件的股票...")
            
            potential_stocks = []
            test_count = 0
            max_test = 100  # 限制测试数量以加快速度
            
            for _, stock in stock_list.iterrows():
                if test_count >= max_test:
                    break
                    
                try:
                    stock_code = stock['code']
                    stock_name = stock['name']
                    
                    # 获取基本信息
                    current_data = self.data_fetcher.get_stock_basic_info(stock_code)
                    
                    if current_data.empty:
                        continue
                    
                    current_price = current_data.get('close', 0)
                    market_cap = current_data.get('market_cap', 0)  # 亿元
                    pe_ratio = current_data.get('pe_ratio', 0)
                    
                    # 应用筛选条件
                    if (self.criteria['min_price'] <= current_price <= self.criteria['max_price'] and
                        market_cap >= self.criteria['min_market_cap'] and
                        self.criteria['min_pe_ratio'] <= pe_ratio <= self.criteria['max_pe_ratio']):
                        
                        # 检查分红情况
                        dividend_score = 0
                        try:
                            dividend_data = self.data_fetcher.get_dividend_info(stock_code)
                            if not dividend_data.empty:
                                dividend_score = len(dividend_data)  # 分红次数作为得分
                        except:
                            pass
                        
                        stock_info = {
                            'code': stock_code,
                            'name': stock_name,
                            'price': current_price,
                            'market_cap': market_cap,
                            'pe_ratio': pe_ratio,
                            'dividend_score': dividend_score,
                            'has_dividend': dividend_score > 0
                        }
                        
                        potential_stocks.append(stock_info)
                        print(f"  ✓ {stock_code} {stock_name}: ¥{current_price:.2f}, 市值{market_cap:.0f}亿, PE{pe_ratio:.1f}")
                        
                except Exception as e:
                    pass
                
                test_count += 1
                
                if test_count % 10 == 0:
                    print(f"    已检查 {test_count} 只股票，找到 {len(potential_stocks)} 只符合条件")
            
            # 按综合得分排序（优先考虑有分红的股票）
            potential_stocks.sort(key=lambda x: (x['has_dividend'], x['dividend_score'], -x['pe_ratio']), reverse=True)
            
            self.print_success(f"筛选完成：从 {test_count} 只股票中找到 {len(potential_stocks)} 只符合条件的股票")
            
            return potential_stocks[:20]  # 返回前20只用于进一步分析
            
        except Exception as e:
            print(f"❌ 股票筛选失败: {e}")
            return []
    
    def select_top_3_stocks(self, potential_stocks):
        """从候选股票中选出最具潜力的3只"""
        self.print_header("第二步：深度分析并选出3只最具潜力的股票")
        
        if len(potential_stocks) < 3:
            print("❌ 候选股票不足3只")
            return []
        
        scored_stocks = []
        
        for stock in potential_stocks[:10]:  # 分析前10只候选股票
            try:
                stock_code = stock['code']
                stock_name = stock['name']
                
                print(f"\n📊 分析 {stock_code} - {stock_name}")
                
                # 获取历史数据
                historical_data = self.data_fetcher.get_stock_data(stock_code, days=120)
                
                if historical_data.empty or len(historical_data) < 60:
                    print(f"  ⚠️  历史数据不足，跳过")
                    continue
                
                # 技术分析评分
                technical_score = self.calculate_technical_score(historical_data)
                
                # 趋势分析评分
                trend_score = self.calculate_trend_score(historical_data)
                
                # 基本面评分
                fundamental_score = self.calculate_fundamental_score(stock)
                
                # 综合评分
                total_score = (
                    technical_score * 0.4 +
                    trend_score * 0.4 +
                    fundamental_score * 0.2
                )
                
                scored_stock = {
                    **stock,
                    'technical_score': technical_score,
                    'trend_score': trend_score,
                    'fundamental_score': fundamental_score,
                    'total_score': total_score
                }
                
                scored_stocks.append(scored_stock)
                
                print(f"  📈 技术分析: {technical_score:.1f}/100")
                print(f"  📊 趋势分析: {trend_score:.1f}/100") 
                print(f"  🏢 基本面: {fundamental_score:.1f}/100")
                print(f"  🎯 综合评分: {total_score:.1f}/100")
                
            except Exception as e:
                print(f"  ❌ 分析失败: {e}")
                continue
        
        # 按综合评分排序
        scored_stocks.sort(key=lambda x: x['total_score'], reverse=True)
        
        # 选出前3只
        top_3 = scored_stocks[:3]
        
        print(f"\n🏆 最终选出的3只潜力股:")
        for i, stock in enumerate(top_3, 1):
            print(f"  {i}. {stock['code']} - {stock['name']}")
            print(f"     价格: ¥{stock['price']:.2f} | 综合评分: {stock['total_score']:.1f}/100")
        
        return top_3
    
    def calculate_technical_score(self, data):
        """计算技术分析评分"""
        try:
            # 获取技术指标
            signal = self.technical_analyzer.get_trading_signal(data)
            
            # 基于技术信号打分
            signal_scores = {
                '强烈买入': 90,
                '买入': 75,
                '持有': 60,
                '卖出': 40,
                '强烈卖出': 20,
                '震荡': 50
            }
            
            base_score = signal_scores.get(signal, 50)
            
            # 计算价格相对位置（近期高低点）
            recent_high = data['high'].tail(20).max()
            recent_low = data['low'].tail(20).min()
            current_price = data['close'].iloc[-1]
            
            if recent_high > recent_low:
                price_position = (current_price - recent_low) / (recent_high - recent_low)
                # 在低位时加分，高位时减分
                position_adjustment = (0.5 - price_position) * 20
                base_score += position_adjustment
            
            return max(0, min(100, base_score))
            
        except:
            return 50
    
    def calculate_trend_score(self, data):
        """计算趋势分析评分"""
        try:
            # 计算多周期移动平均线
            data['ma5'] = data['close'].rolling(5).mean()
            data['ma20'] = data['close'].rolling(20).mean()
            data['ma60'] = data['close'].rolling(60).mean()
            
            current_price = data['close'].iloc[-1]
            ma5 = data['ma5'].iloc[-1]
            ma20 = data['ma20'].iloc[-1]
            ma60 = data['ma60'].iloc[-1]
            
            score = 50
            
            # 多头排列加分
            if current_price > ma5 > ma20 > ma60:
                score += 30
            elif current_price > ma5 > ma20:
                score += 20
            elif current_price > ma5:
                score += 10
            
            # 计算成交量趋势
            volume_ma = data['volume'].rolling(20).mean()
            recent_volume = data['volume'].tail(5).mean()
            if recent_volume > volume_ma.iloc[-1]:
                score += 15  # 成交量放大
            
            # 计算价格动量
            price_change = (current_price - data['close'].iloc[-20]) / data['close'].iloc[-20]
            if price_change > 0.1:  # 20天涨幅超过10%
                score += 15
            elif price_change > 0.05:  # 20天涨幅超过5%
                score += 10
            
            return max(0, min(100, score))
            
        except:
            return 50
    
    def calculate_fundamental_score(self, stock):
        """计算基本面评分"""
        score = 50
        
        # PE估值评分
        pe_ratio = stock.get('pe_ratio', 15)
        if 5 <= pe_ratio <= 15:
            score += 25  # 估值合理
        elif 15 < pe_ratio <= 25:
            score += 15  # 估值偏高但可接受
        elif pe_ratio > 25:
            score += 5   # 估值偏高
        
        # 市值规模评分
        market_cap = stock.get('market_cap', 100)
        if 100 <= market_cap <= 500:
            score += 20  # 中等市值，成长空间大
        elif 50 <= market_cap < 100:
            score += 15  # 小市值，风险较高
        elif market_cap >= 500:
            score += 10  # 大市值，相对稳定
        
        # 分红评分
        if stock.get('has_dividend', False):
            score += 15  # 有分红历史
            if stock.get('dividend_score', 0) >= 5:
                score += 10  # 分红记录良好
        
        return max(0, min(100, score))
    
    def analyze_selected_stocks(self, selected_stocks):
        """深度分析选中的股票"""
        self.print_header("第三步：深度分析选中股票的投资价值")
        
        for i, stock in enumerate(selected_stocks, 1):
            stock_code = stock['code']
            stock_name = stock['name']
            
            print(f"\n🔍 深度分析 #{i}: {stock_code} - {stock_name}")
            print(f"💰 当前价格: ¥{stock['price']:.2f}")
            print(f"📊 市值: {stock['market_cap']:.0f}亿元")
            print(f"📈 市盈率: {stock['pe_ratio']:.1f}")
            print(f"🎁 分红情况: {'有分红记录' if stock['has_dividend'] else '无分红记录'}")
            
            try:
                # 获取更长期的历史数据用于深度分析
                historical_data = self.data_fetcher.get_stock_data(stock_code, days=252)  # 1年数据
                
                if historical_data.empty:
                    print("  ❌ 无法获取历史数据")
                    continue
                
                # 分析历史价格行为
                self.analyze_price_behavior(historical_data, stock_name)
                
                # 分析未来1个月趋势
                self.predict_monthly_trend(historical_data, stock_code, stock_name)
                
                # 风险评估
                self.assess_investment_risk(historical_data, stock_name)
                
                # 投资建议
                self.generate_investment_advice(stock, historical_data)
                
            except Exception as e:
                print(f"  ❌ 深度分析失败: {e}")
    
    def analyze_price_behavior(self, data, stock_name):
        """分析股票价格行为习惯"""
        print(f"\n  📈 {stock_name} 价格行为分析:")
        
        # 波动率分析
        returns = data['close'].pct_change().dropna()
        volatility = returns.std() * np.sqrt(252) * 100  # 年化波动率
        
        # 最大回撤分析
        rolling_max = data['close'].expanding().max()
        drawdown = (data['close'] - rolling_max) / rolling_max * 100
        max_drawdown = drawdown.min()
        
        # 趋势持续性分析
        data['ma20'] = data['close'].rolling(20).mean()
        above_ma20 = (data['close'] > data['ma20']).sum() / len(data) * 100
        
        # 价格区间分析
        price_high = data['close'].max()
        price_low = data['close'].min()
        current_price = data['close'].iloc[-1]
        price_position = (current_price - price_low) / (price_high - price_low) * 100
        
        print(f"    💫 年化波动率: {volatility:.1f}%")
        print(f"    📉 最大回撤: {max_drawdown:.1f}%")
        print(f"    📊 趋势稳定性: {above_ma20:.1f}%时间位于20日均线上方")
        print(f"    📍 当前位置: 在年度价格区间的{price_position:.1f}%位置")
        
        if volatility < 25:
            print(f"    ✅ 波动率较低，属于稳健型股票")
        elif volatility < 40:
            print(f"    ⚠️  波动率中等，需要注意风险控制")
        else:
            print(f"    🔴 波动率较高，属于高风险股票")
    
    def predict_monthly_trend(self, data, stock_code, stock_name):
        """预测未来1个月趋势"""
        print(f"\n  🔮 {stock_name} 未来1个月趋势预测:")
        
        try:
            # 使用预测模型
            prediction = self.prediction_model.predict_price(data, stock_code)
            
            if prediction and 'trend' in prediction:
                trend = prediction['trend']
                confidence = prediction.get('confidence', 0) * 100
                
                trend_icons = {
                    '上涨': '📈',
                    '下跌': '📉', 
                    '震荡': '📊'
                }
                
                icon = trend_icons.get(trend, '📊')
                print(f"    {icon} 预测趋势: {trend}")
                print(f"    🎯 预测置信度: {confidence:.1f}%")
                
                if 'next_day_price' in prediction:
                    current_price = data['close'].iloc[-1]
                    predicted_price = prediction['next_day_price']
                    change_pct = (predicted_price - current_price) / current_price * 100
                    
                    print(f"    💰 当前价格: ¥{current_price:.2f}")
                    print(f"    🎯 预测价格: ¥{predicted_price:.2f}")
                    print(f"    📊 预期涨跌: {change_pct:+.2f}%")
                
                # 技术面分析
                signal = self.technical_analyzer.get_trading_signal(data)
                print(f"    📊 技术信号: {signal}")
                
            else:
                print(f"    ❌ 预测模型暂时无法给出明确预测")
                
        except Exception as e:
            print(f"    ❌ 预测失败: {e}")
    
    def assess_investment_risk(self, data, stock_name):
        """评估投资风险"""
        print(f"\n  ⚖️  {stock_name} 投资风险评估:")
        
        # 计算风险指标
        returns = data['close'].pct_change().dropna()
        
        # VaR计算（95%置信度）
        var_95 = np.percentile(returns, 5) * 100
        
        # 夏普比率计算（假设无风险利率3%）
        excess_returns = returns.mean() * 252 - 0.03
        volatility = returns.std() * np.sqrt(252)
        sharpe_ratio = excess_returns / volatility if volatility > 0 else 0
        
        # 最大连续下跌天数
        negative_returns = returns < 0
        max_consecutive_down = 0
        current_consecutive = 0
        for is_negative in negative_returns:
            if is_negative:
                current_consecutive += 1
                max_consecutive_down = max(max_consecutive_down, current_consecutive)
            else:
                current_consecutive = 0
        
        print(f"    📉 95% VaR (单日最大损失): {var_95:.2f}%")
        print(f"    📊 夏普比率: {sharpe_ratio:.2f}")
        print(f"    📅 最大连续下跌天数: {max_consecutive_down}天")
        
        # 风险等级评估
        if abs(var_95) < 3 and sharpe_ratio > 0.5:
            risk_level = "🟢 低风险"
        elif abs(var_95) < 5 and sharpe_ratio > 0:
            risk_level = "🟡 中等风险"
        else:
            risk_level = "🔴 高风险"
        
        print(f"    🎯 风险等级: {risk_level}")
    
    def generate_investment_advice(self, stock, data):
        """生成投资建议"""
        print(f"\n  💡 投资建议:")
        
        current_price = stock['price']
        pe_ratio = stock['pe_ratio']
        has_dividend = stock['has_dividend']
        total_score = stock['total_score']
        
        # 基于综合分析给出建议
        if total_score >= 80:
            if has_dividend and pe_ratio <= 20:
                advice = "🟢 强烈推荐 - 优质价值股，适合中长期持有"
                position = "建议仓位: 10-15%"
            else:
                advice = "🟢 推荐买入 - 具备较好投资价值"
                position = "建议仓位: 8-12%"
        elif total_score >= 65:
            advice = "🟡 谨慎关注 - 可考虑小仓位试探"
            position = "建议仓位: 3-5%"
        else:
            advice = "🔴 暂不推荐 - 风险较高或价值不明显"
            position = "建议仓位: 0%"
        
        print(f"    {advice}")
        print(f"    📊 {position}")
        
        # 买入时机建议
        recent_high = data['high'].tail(20).max()
        recent_low = data['low'].tail(20).min()
        price_position = (current_price - recent_low) / (recent_high - recent_low)
        
        if price_position < 0.3:
            timing = "💰 当前处于近期低位，是较好的买入时机"
        elif price_position < 0.7:
            timing = "📊 当前价格适中，可分批建仓"
        else:
            timing = "⚠️  当前处于近期高位，建议等待回调"
        
        print(f"    {timing}")
        
        # 止损建议
        stop_loss = current_price * 0.85  # 15%止损
        take_profit = current_price * 1.25  # 25%止盈
        
        print(f"    🛑 建议止损价: ¥{stop_loss:.2f} (-15%)")
        print(f"    🎯 建议止盈价: ¥{take_profit:.2f} (+25%)")
    
    def run_complete_analysis(self):
        """运行完整的投资分析流程"""
        print(f"""
🎯 A股中长期投资分析系统
📅 分析时间: {datetime.now().strftime('%Y年%m月%d日 %H:%M')}

💰 投资策略:
   - 市值范围: 50亿 - 2000亿
   - 价格区间: 4元 - 20元  
   - 市盈率: 5 - 30倍
   - 优先考虑: 有分红记录的公司
   - 投资周期: 中长期（1个月以上）

🚀 开始分析...
        """)
        
        # 第一步：筛选潜力股票
        potential_stocks = self.screen_potential_stocks()
        
        if len(potential_stocks) < 3:
            print("❌ 符合条件的股票太少，无法完成分析")
            return
        
        # 第二步：选出Top 3
        top_3_stocks = self.select_top_3_stocks(potential_stocks)
        
        if len(top_3_stocks) < 3:
            print("❌ 无法选出3只潜力股票")
            return
        
        # 第三步：深度分析
        self.analyze_selected_stocks(top_3_stocks)
        
        # 第四步：生成投资组合建议
        self.generate_portfolio_advice(top_3_stocks)
        
        print(f"\n🎉 分析完成！")
        print(f"💡 请记住：投资有风险，以上分析仅供参考，不构成投资建议")
        print(f"📊 建议结合自己的风险承受能力和投资目标做出决策")
    
    def generate_portfolio_advice(self, selected_stocks):
        """生成投资组合建议"""
        self.print_header("第四步：投资组合建议")
        
        total_score = sum(stock['total_score'] for stock in selected_stocks)
        
        print("📊 建议投资组合配置:")
        
        for i, stock in enumerate(selected_stocks, 1):
            weight = (stock['total_score'] / total_score) * 100
            print(f"  {i}. {stock['code']} - {stock['name']}")
            print(f"     建议权重: {weight:.1f}%")
            print(f"     投资理由: 综合评分{stock['total_score']:.1f}/100")
            
        print(f"\n💰 资金配置建议:")
        print(f"  - 总仓位: 建议不超过总资金的30-40%")
        print(f"  - 分批建仓: 分2-3次买入，间隔1-2周") 
        print(f"  - 止损策略: 单只股票跌幅超过15%考虑止损")
        print(f"  - 定期复查: 每月重新评估一次投资组合")

if __name__ == "__main__":
    analyzer = MediumTermInvestmentAnalyzer()
    analyzer.run_complete_analysis()
